﻿using System;
using System.Diagnostics;
using System.IO;

namespace Redmine.Laptop.Common.Core
{
    /// <summary>
    /// File Storage
    /// </summary>
    public class FileStorage
    {
        #region Properties
        /// <summary>
        /// File path
        /// </summary>
        public string Path { get; private set; }

        /// <summary>
        /// File name
        /// </summary>
        public string Name { get; private set; }

        /// <summary>
        /// File extension
        /// </summary>
        public string Extension { get; private set; }

        /// <summary>
        /// Unique file key
        /// </summary>
        public string UniqueKey { get; private set; }

        /// <summary>
        /// flag indicating whether the file is a temporary
        /// </summary>
        public bool IsTempFile { get; private set; }

        #endregion

        #region Constructor

        /// <summary>
        /// Create a new file storage using filepath
        /// </summary>
        /// <param name="filepath"></param>
        public FileStorage(string filepath)
        {
            Path = filepath;
            Name = System.IO.Path.GetFileName(Path);
            UniqueKey = Guid.NewGuid().ToString();
            Extension = System.IO.Path.GetExtension(Path);
        }

        /// <summary>
        /// Create a new file storage using filepath and file's bytes array
        /// </summary>
        /// <param name="filepath"></param>
        /// <param name="bytes"></param>
        public FileStorage(string filepath, byte[] bytes)
            : this(filepath)
        {
            File.WriteAllBytes(filepath, bytes);
        }
        #endregion

        /// <summary>
        /// Determines whether the specified FileStorage exists 
        /// </summary>
        /// <returns></returns>
        public bool Exists()
        {
            return File.Exists(Path);
        }

        /// <summary>
        /// Copy file storage to the specified path
        /// </summary>
        /// <param name="destinationPath"></param>
        /// <returns></returns>               
        public FileStorage CopyTo(string destinationPath)
        {
            File.Copy(Path, destinationPath, true);
            return new FileStorage(destinationPath);
        }

        /// <summary>
        /// Copy file storage to the specified folder
        /// If isUseOriginalFileName set as true, use original file name while copying
        /// If isUseOriginalFileName set as false, use unique key instead of filename while copying
        /// </summary>
        /// <param name="destinationFolderPath">Folder path for copying</param>
        /// <param name="isUseOriginalFileName">Determines whether using original filename while copying</param>
        /// <returns></returns>
        public FileStorage CopyToFolder(string destinationFolderPath, bool isUseOriginalFileName = true)
        {
            var filename = isUseOriginalFileName ? Name : UniqueKey + Extension;
            var newFilePath = System.IO.Path.Combine(destinationFolderPath, filename);

            return CopyTo(newFilePath);
        }

        /// <summary>
        /// Open file using default program for this file type
        /// </summary>
        public void Open()
        {
            Process.Start(Path);
        }

        /// <summary>
        /// Method provides a functionality for physical delete FileStorage 
        /// </summary>
        public void Delete()
        {
            File.Delete(Path);
        }

        public static FileStorage GetTempFile()
        {
            var path = System.IO.Path.GetTempPath();

            var tempFile = new FileStorage(path)
            {
                IsTempFile = true
            };

            return tempFile;
        }

        public static FileStorage GetTempFile(byte[] bytes)
        {
            var path = System.IO.Path.GetTempPath();

            var tempFile = new FileStorage(path, bytes)
            {
                IsTempFile = true
            };

            return tempFile;
        }
    }
}
